package com.example.easybuy.util;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.action.DocWriteResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Map;

@Component
public class ElasticsearchUtil {

    @Autowired
    private RestHighLevelClient client;

    private final ObjectMapper objectMapper = new ObjectMapper();

    /**
     * 创建索引
     *
     * @param index 索引名称
     * @return 是否创建成功
     * @throws IOException IO异常
     */
    public boolean createIndex(String index) throws IOException {
        GetIndexRequest request = new GetIndexRequest(index);
        boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
        if (!exists) {
            CreateIndexRequest createIndexRequest = new CreateIndexRequest(index);
            CreateIndexResponse createIndexResponse = client.indices().create(createIndexRequest, RequestOptions.DEFAULT);
            return createIndexResponse.isAcknowledged();
        }
        return false;
    }

    /**
     * 检查索引是否存在
     *
     * @param index 索引名称
     * @return 是否存在
     * @throws IOException IO异常
     */
    public boolean indexExists(String index) throws IOException {
        GetIndexRequest request = new GetIndexRequest(index);
        return client.indices().exists(request, RequestOptions.DEFAULT);
    }

    /**
     * 保存或更新文档
     *
     * @param index 索引名称
     * @param id    文档ID
     * @param data  文档数据
     * @return 文档ID
     * @throws IOException IO异常
     */
    public String save(String index, String id, Object data) throws IOException {
        IndexRequest request = new IndexRequest(index).id(id);
        String jsonString = objectMapper.writeValueAsString(data);
        request.source(jsonString, XContentType.JSON);
        IndexResponse response = client.index(request, RequestOptions.DEFAULT);
        return response.getId();
    }

    /**
     * 根据ID获取文档
     *
     * @param index 索引名称
     * @param id    文档ID
     * @return 文档内容
     * @throws IOException IO异常
     */
    public Map<String, Object> getById(String index, String id) throws IOException {
        GetRequest request = new GetRequest(index, id);
        GetResponse response = client.get(request, RequestOptions.DEFAULT);
        if (response.isExists()) {
            return response.getSource();
        }
        return null;
    }

    /**
     * 根据ID更新文档
     *
     * @param index 索引名称
     * @param id    文档ID
     * @param data  更新数据
     * @return 是否更新成功
     * @throws IOException IO异常
     */
    public boolean update(String index, String id, Object data) throws IOException {
        UpdateRequest request = new UpdateRequest(index, id);
        String jsonString = objectMapper.writeValueAsString(data);
        request.doc(jsonString, XContentType.JSON);
        UpdateResponse response = client.update(request, RequestOptions.DEFAULT);
        return response.getResult() == DocWriteResponse.Result.UPDATED || response.getResult() == DocWriteResponse.Result.CREATED;
    }

    /**
     * 根据ID删除文档
     *
     * @param index 索引名称
     * @param id    文档ID
     * @return 是否删除成功
     * @throws IOException IO异常
     */
    public boolean deleteById(String index, String id) throws IOException {
        DeleteRequest request = new DeleteRequest(index, id);
        DeleteResponse response = client.delete(request, RequestOptions.DEFAULT);
        return response.getResult() == DocWriteResponse.Result.DELETED;
    }

    /**
     * 搜索所有文档
     *
     * @param index 索引名称
     * @return 搜索结果
     * @throws IOException IO异常
     */
    public SearchResponse searchAll(String index) throws IOException {
        SearchRequest searchRequest = new SearchRequest(index);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.matchAllQuery());
        searchRequest.source(searchSourceBuilder);
        return client.search(searchRequest, RequestOptions.DEFAULT);
    }
}